package com.hsy.crm.web.service.asyn.marketprofit;

import com.hsy.crm.web.domain.cm.App;
import com.hsy.crm.web.domain.entity.Message;
import com.hsy.crm.web.domain.entity.SaleCostDetail;
import com.hsy.crm.web.domain.entity.StoreProduct;
import com.hsy.crm.web.domain.entity.StoreProductDetail;
import com.hsy.crm.web.domain.po.account.DivResult;
import com.hsy.crm.web.domain.po.asyn.CostResult;
import com.hsy.crm.web.domain.po.asyn.ProductCostPo;
import com.hsy.crm.web.mapper.SaleCostDetailMapper;
import com.hsy.crm.web.mapper.StoreProductDetailMapper;
import com.hsy.crm.web.mapper.StoreProductMapper;
import com.hsy.crm.web.utils.CalcUtils;
import com.hsy.crm.web.utils.UuidUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 销售单审核    --   出库
 */
@Service
public class SaleProfitService {

    @Autowired
    StoreProductDetailMapper storeProductDetailMapper;

    @Autowired
    SaleCostDetailMapper saleCostDetailMapper;

    @Autowired
    StoreProductMapper storeProductMapper;

    public void init(Message message, List<StoreProductDetail> storeProductDetails){
        for (StoreProductDetail storeProductDetail : storeProductDetails){
            this.calcStoreProductDetailDone(message,storeProductDetail);
        }
    }

    public long calcStoreProductDetailDone(Message message,StoreProductDetail currStoreProductDetail){
        return this.calcStoreProductDetail(message,currStoreProductDetail,null);
    }

    /*public void calcStoreProductDetailDone(Message message,StoreProductDetail currStoreProductDetail,StoreProductDetail firstStoreProductDetail){
        this.calcStoreProductDetail(message,currStoreProductDetail,firstStoreProductDetail);
    }*/

    /**
     * 处理具体的某一个明细的利润情况
     *
     * 处理过程：
     *      update t_store_product_detail set out_number out_price  relation_start_sort relation_end_sort
     * 处理完成：
     *      update t_store_product_detail set tmp_price = 0
     * 无库存时：
     *      update t_store_product_detail set tmp_price = 最后一次进货成本
     * @param message
     * @param currStoreProductDetail    待处理的明细
     * @param firstStoreProductDetail   指定以该明细库存算利润
     */
    private long calcStoreProductDetail(Message message,StoreProductDetail currStoreProductDetail,StoreProductDetail firstStoreProductDetail){

        long this_out_number = 0;

        //查询 未指定以哪条明细算利润时  查询最早一次库存明细（先进所以先出）
        if( firstStoreProductDetail == null ){
            firstStoreProductDetail = this.getFirstStoreProductDetail(message,currStoreProductDetail);
        }

        //更新 无库存时  成本按照最后一次进货成本处理
        if( firstStoreProductDetail == null || firstStoreProductDetail.getId() == null ){
            this.noStock(currStoreProductDetail);
            storeProductDetailMapper.addOutTmp(currStoreProductDetail);
            return this_out_number;
        }

        firstStoreProductDetail.setCustomerId(message.getCustomerId());

        //属性获取 获取本次出库数量和成本
        CostResult costResult = getCostResult(firstStoreProductDetail,currStoreProductDetail);

        //属性设置 设置sort 起始sort无值则设置为起始  起始sort有值则设置为结束
        this.setCurrSort(currStoreProductDetail,firstStoreProductDetail);

        //属性设置  设置本次 出库总数量 出库总金额
        this.setCurrStoreProductDetail(currStoreProductDetail,costResult);

        this_out_number = costResult.getNumber().longValue();

        //数据更新  out_number out_price  起止sort
        storeProductDetailMapper.addOut(currStoreProductDetail);

        //数据更新  out_number out_price  起止sort
        this.setFirstStoreProducctDetail(firstStoreProductDetail,costResult);
        this.setFirstSort(currStoreProductDetail,firstStoreProductDetail);
        storeProductDetailMapper.addOut(firstStoreProductDetail);

        //更新主库存成本总额
        this.updateStoreProduct(message,firstStoreProductDetail,costResult);

        //添加销售成本明细
        this.addSaleCostDetail(message,currStoreProductDetail,firstStoreProductDetail,costResult);

        if( costResult.isDone() ){
            //处理完成 清理临时数据
            storeProductDetailMapper.clearTmp(currStoreProductDetail);
            return this_out_number;
        }else{
            //未处理完成则继续
            this_out_number += calcStoreProductDetail(message,currStoreProductDetail,null);
        }

        return this_out_number;

    }

    private void updateStoreProduct(Message message,StoreProductDetail storeProductDetail,CostResult costResult){
        StoreProduct storeProduct = new StoreProduct();
        storeProduct.setId(storeProductDetail.getStoreProductId());
        storeProduct.setCustomerId(message.getCustomerId());
        storeProduct.setPrice(costResult.getCost());
        storeProductMapper.updatePrice(storeProduct);
    }

    private void addSaleCostDetail(Message message,StoreProductDetail currStoreProductDetail,StoreProductDetail firstStoreProductDetail ,CostResult costResult){
        SaleCostDetail detail = new SaleCostDetail();
        detail.setId(UuidUtils.getUuid());
        detail.setInStoreProductDetailId(firstStoreProductDetail.getId());
        detail.setOutStoreProductDetailId(currStoreProductDetail.getId());
        detail.setOutNumber(costResult.getNumber());
        detail.setOutPrice(costResult.getCost());
        detail.setBackNumber(0L);
        detail.setBackPrice(0L);
        detail.setCustomerId(message.getCustomerId());
        detail.setInTime(firstStoreProductDetail.getTime());
        detail.setOutTime(currStoreProductDetail.getTime());
        detail.setSaleCostDetailId(0L);//?
        saleCostDetailMapper.insert(detail);
    }

    private void noStock(StoreProductDetail currStoreProductDetail){
        ProductCostPo productCost = storeProductDetailMapper.selectLastBuyCost(currStoreProductDetail);
        Long cost = -2L;
        if( productCost != null ){
            StoreProductDetail tmpStoreProductDetail = storeProductDetailMapper.selectByPrimaryKey(currStoreProductDetail);
            cost = CalcUtils.div(productCost.getStockTotalPrice(),productCost.getStockTotalNumber());
            Long number = tmpStoreProductDetail.getNumber() - tmpStoreProductDetail.getOutNumber();
            cost = CalcUtils.mul(number,cost);
        }

        currStoreProductDetail.setTmpPrice(cost.longValue());
    }

    private CostResult getCostResult(StoreProductDetail firstStoreProductDetail, StoreProductDetail currStoreProductDetail){
        DivResult result = CalcUtils.result(firstStoreProductDetail.getNumber(),firstStoreProductDetail.getPrice());
        Long cost; Long number;boolean done;

        long firstElseNumber = firstStoreProductDetail.getNumber() - firstStoreProductDetail.getOutNumber();
        long currElseNumber = currStoreProductDetail.getNumber() - currStoreProductDetail.getOutNumber();

        if( firstElseNumber > currElseNumber ){
            number = currElseNumber;
            cost = CalcUtils.mul(result.getSmall(),number);
            cost = CalcUtils.div100(cost);
            done = true;
        }else{
            number = firstElseNumber == currElseNumber ? currElseNumber : firstElseNumber;
            if( result.getStrong() == 0 ){
                cost = CalcUtils.mul(result.getSmall(),number);
                cost = CalcUtils.div100(cost);
            }else{
                cost = CalcUtils.mul(result.getSmall(),(Long)(number-App.DECIMAL.DIV));
                cost = CalcUtils.div100(cost);
                cost = CalcUtils.add(cost,result.getStrong());
            }
            done = firstElseNumber == currElseNumber;
        }
        return new CostResult(number,cost,done);
    }

    private void setCurrStoreProductDetail(StoreProductDetail currStoreProductDetail,CostResult costResult){
        currStoreProductDetail.setOutNumber(costResult.getNumber());
        currStoreProductDetail.setOutPrice(costResult.getCost());
    }

    private void setFirstStoreProducctDetail(StoreProductDetail firstStoreProductDetail,CostResult costResult){
        firstStoreProductDetail.setOutNumber(costResult.getNumber());
        firstStoreProductDetail.setOutPrice(costResult.getCost());
    }

    private void setCurrSort(StoreProductDetail currStoreProductDetail,StoreProductDetail firstStoreProductDetail){
        if( currStoreProductDetail.getRelationStartSort() == -1 ){
            currStoreProductDetail.setRelationStartSort(firstStoreProductDetail.getSort());
        }else{
            currStoreProductDetail.setRelationEndSort(firstStoreProductDetail.getSort());
        }
    }

    private void setFirstSort(StoreProductDetail currStoreProductDetail,StoreProductDetail firstStoreProductDetail){
        if( firstStoreProductDetail.getRelationStartSort() == -1 ){
            firstStoreProductDetail.setRelationStartSort(currStoreProductDetail.getSort());
        }else{
            firstStoreProductDetail.setRelationEndSort(currStoreProductDetail.getSort());
        }
    }


    private StoreProductDetail getFirstStoreProductDetail(Message message,StoreProductDetail currStoreProductDetail){
        //寻思有没有批次号  没有批次号用原来的逻辑
        StoreProductDetail storeProductDetail = new StoreProductDetail();
        storeProductDetail.setStoreProductId(currStoreProductDetail.getStoreProductId());
        storeProductDetail.setCustomerId(message.getCustomerId());
        storeProductDetail.setBatchNo(currStoreProductDetail.getBatchNo());// add this row , nice
        return storeProductDetailMapper.getFirstStoreProductDetail(storeProductDetail);
    }

}
